package com.itstyle.seckill.topic.jichu;

import java.util.concurrent.*;

/**
 * @Auther: liuwenxiang
 * @Date: 2020/3/16 11:58
 * @Description:
 */
public class TestThreadHelp {

    private static ExecutorService executorService = Executors.newCachedThreadPool();

    private static Exchanger<String> exchanger = new Exchanger<String>();

    private static Semaphore semaphore = new Semaphore(2);//一共两个信号量（两个停车位）

    private static CyclicBarrier cyclicBarrier =new CyclicBarrier(3, new Runnable() {
        @Override
        public void run() {
            System.out.println("所有线程准备就绪，开始起跑");
        }
    });

    public static void main(String[] args) {
        //testExchanger();
        testSemaphore();
        //testCyclicBarrier();
        System.out.println("我是主线程");
    }



    public static  void testCyclicBarrier(){

        /**
         * 1.CyclicBarrier设置位3，这里4次循环，其实循环3次后，CyclicBarrier中的线程就开始执行了。
         * 2.每个线程执行到cyclicBarrier.await();就会暂停，当所有的屏障用完了，所有线程才继续执行。
         * 3.主线程等CyclicBarrier执行完了，再执行。
         */
        for (int i=0;i<4;i++){


            executorService.execute(new Runnable() {
                @Override
                public void run() {
                    System.out.println(Thread.currentThread()+"准备好了");
                    try {
                        cyclicBarrier.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } catch (BrokenBarrierException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread()+"奋力奔跑中");
                }
            });
        }



    }



    /**
     * CyclicBarrier 的枚举辅助类
     */
     enum CyclicBarrierEnum {
        ONE(1, "班长"), TWO(2, "副班长"), THREE(3, "学习委员"), FORE(4, "纪律委员"), FINE(5, "生活委员"), SIT(6, "劳动委员"), SERVE(7, "团支书");
        private int retCode;
        private String retMessenger;

        public int getRetCode() {
            return retCode;
        }

        public String getRetMessenger() {
            return retMessenger;
        }

        CyclicBarrierEnum(int retCode, String retMessenger) {
            this.retCode = retCode;
            this.retMessenger = retMessenger;
        }

        public static CyclicBarrierEnum getMessenger(int index) {
            CyclicBarrierEnum[] elemts = CyclicBarrierEnum.values();
            for (CyclicBarrierEnum iter : elemts) {
                if (iter.getRetCode() == index) {
                    return iter;
                }
            }
            return null;
        }
    }


    private static void testSemaphore() {
        for (int i = 0; i < 6; i++) {

            executorService.execute(new Runnable() {
                @Override
                public void run() {
                    //占用一个信号量
                    try {
                        semaphore.acquire();//占用一个停车位
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName() + "获取停车位");
                    //占用3秒
                    try {
                        TimeUnit.SECONDS.sleep(3);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName() + "\t 停车3秒后,离开停车场");
                    //释放
                    semaphore.release();

                }
            });
        }
    }


    public static void testExchanger() {

        /**
         * 1.exchanger进行线程间的数据交换，它提供了一个同步点，在这个同步点，两个线程可以交换数据。
         *   如果一个线程先执行了exchanger，那么它会等到第二个线程执行exchanger方法，当两个线程都到了执行exchanger的位置，就可以进行数据交换了。
         * 2.exchanger应用场景，两个线程交换数据。
         */
        executorService.execute(new Runnable() {
            @Override
            public void run() {
                String a = "a线程";
                try {
                    String a1 = exchanger.exchange(a);
                    System.out.println("1:" + a1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        executorService.execute(new Runnable() {
            @Override
            public void run() {
                String b = "b线程";
                try {
                    String b1 = exchanger.exchange(b);
                    System.out.println("2:" + b1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

       /* executorService.execute(new Runnable() {
            @Override
            public void run() {
                String c ="c线程";
                try {
                    String c1 = exchanger.exchange(c);
                    System.out.println("3:"+c1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
*/

        executorService.shutdown();
    }


}
